package main

import (
	"encoding/binary"
	"encoding/json"
	"fmt"
	"math"
	"modbusComm/db"
	"modbusComm/model"
	"os"
	"time"

	"github.com/goburrow/modbus"
)

func getBigDecimalFromHex(bs []byte, num int) float64 {
	n := binary.BigEndian.Uint16(bs)
	return math.Pow10(-num) * float64(n)
}

func parseData(registers []byte, slave model.Slave, now time.Time) {
	pst := getBigDecimalFromHex(registers[1*2:], 0)  //供电时间
	btr := getBigDecimalFromHex(registers[2*2:], 0)  //剩余时间
	brc := getBigDecimalFromHex(registers[3*2:], 0)  //剩余容量
	bu := getBigDecimalFromHex(registers[4*2:], 1)   //电池电压
	bi := getBigDecimalFromHex(registers[5*2:], 1)   //电池电流
	tmp := getBigDecimalFromHex(registers[6*2:], 0)  //电池温度
	iu := getBigDecimalFromHex(registers[9*2:], 0)   //输入电压
	ifq := getBigDecimalFromHex(registers[15*2:], 1) //输入频率
	ofq := getBigDecimalFromHex(registers[25*2:], 1) //输出频率
	ou := getBigDecimalFromHex(registers[27*2:], 0)  //输出电压
	lp := getBigDecimalFromHex(registers[39*2:], 0)  //负载百分比
	bfq := getBigDecimalFromHex(registers[42*2:], 1) //旁路频率
	msgs <- model.UpsRunInfo{
		Stcd:   slave.Stcd,
		Tm:     time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), 0, 0, now.Location()),
		Pstm:   pst,
		RemTm:  btr,
		RemCap: brc,
		BatU:   bu,
		BatI:   bi,
		Tmp:    tmp,
		Iu:     iu,
		Ifq:    ifq,
		Ofq:    ofq,
		Ou:     ou,
		Lp:     lp,
		Bfq:    bfq,
	}
}

func ReadData(client modbus.Client, slave model.Slave) {
	now := time.Now()
	registers, err := client.ReadInputRegisters(0x0101, 0x2B)
	if err != nil {
		fmt.Println(err)
		return
	}
	go parseData(registers, slave, now)
}

func start(slave model.Slave) {
	now := time.Now()
	mi := now.Minute()
	if mi > 0 {
		time.Sleep(time.Minute * time.Duration(60-mi))
	}
	handler := modbus.NewTCPClientHandler(slave.Ip + ":502")
	handler.SlaveId = 1
	handler.Timeout = 5 * time.Second
	client := modbus.NewClient(handler)
	ticker := time.NewTicker(1 * time.Hour)
	ReadData(client, slave)
	for range ticker.C {
		ReadData(client, slave)
	}
}

var slaves []model.Slave

var msgs = make(chan model.UpsRunInfo, 10)

func init() {
	f, err := os.Open("config/config.json")
	if err != nil {
		panic(err)
	}

	err = json.NewDecoder(f).Decode(&slaves)
	if err != nil {
		panic(err)
	}

}

func startTask() {
	for _, slave := range slaves {
		go start(slave)
	}

	for msg := range msgs {
		res := db.GetDB().Create(&msg)
		if res.Error != nil {
			fmt.Println(res.Error)
		}
	}
}

func main() {
	startTask()
}
